package com.samphanie.auiu.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.samphanie.auiu.admin.domain.vo.RoleVo;
import com.samphanie.auiu.admin.service.ISysResourceService;
import com.samphanie.auiu.admin.service.ISysRoleMenuService;
import com.samphanie.auiu.admin.service.ISysRoleResourceService;
import com.samphanie.auiu.admin.service.ISysRoleService;
import com.samphanie.auiu.admin.utils.SecurityUtil;
import com.samphanie.auiu.common.dto.RoleDto;
import com.samphanie.auiu.mbg.mapper.RoleMapper;
import com.samphanie.auiu.mbg.model.SysRole;
import com.samphanie.auiu.mbg.model.SysRoleMenu;
import com.samphanie.auiu.mbg.model.SysRoleResource;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Dries
 * @email 1451691457@qq.com
 */
@Service
@RequiredArgsConstructor
public class ISysRoleServiceImpl extends ServiceImpl<RoleMapper, SysRole> implements ISysRoleService {

    private final ISysRoleMenuService roleMenuService;
    private final ISysRoleResourceService roleResourceService;
    private final ISysResourceService resourceService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean add(RoleDto roleDto) {
        val role = new SysRole();
        BeanUtils.copyProperties(roleDto, role);
        role.setRoleName(roleDto.getRoleName().toUpperCase());

        role.setCreateBy(SecurityUtil.getCurrentUsername());
        return save(role);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateRole(RoleDto roleDto) {
        val role = new SysRole();
        BeanUtils.copyProperties(roleDto, role);
        String name = role.getRoleName().toUpperCase();
        role.setRoleName(name);

        // 关联菜单
        boolean menuResult = roleMenuService.addRoleMenu(roleDto.getId(), roleDto.getMenus());
        // 关联资源
        boolean resourceResult = roleResourceService.addRoleResource(roleDto.getId(), roleDto.getResources());
        resourceService.initResourceRolesMap();
        role.setUpdateBy(SecurityUtil.getCurrentUsername());
        return updateById(role);
    }

    @Override
    public List<RoleVo> listRoleList() {
        val list = list(new LambdaQueryWrapper<SysRole>()
                .eq(SysRole::isStatus, true)
                .eq(SysRole::isStatus, true)
                .orderByDesc(SysRole::getSort)
                .orderByAsc(SysRole::getCreateTime)
        );
        if (CollUtil.isNotEmpty(list)) {
            return list.stream().map(item -> {
//                String name = item.getRoleName();
//                if (StrUtil.startWith(name, AuiuConstants.ROLE_PREFIX)) {
//                    String role = name.replace(AuiuConstants.ROLE_PREFIX, "");
//                    item.setRoleName(role);
//                }
                val roleVo = new RoleVo();
                BeanUtils.copyProperties(item, roleVo);
                val roleMenus = roleMenuService.listByRoleId(item.getId());
                if (CollUtil.isNotEmpty(roleMenus)) {
                    roleVo.setMenus(roleMenus.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toSet()));
                }
                val roleResources = roleResourceService.listByRoleId(item.getId());
                if (CollUtil.isNotEmpty(roleResources)) {
                    roleVo.setResources(roleResources.stream().map(SysRoleResource::getResourceId).collect(Collectors.toSet()));
                }
                return roleVo;
            }).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public List<String> getRolesNames() {
        val list = list(new LambdaQueryWrapper<SysRole>()
                .eq(SysRole::isStatus, true)
                .orderByDesc(SysRole::getSort)
                .orderByAsc(SysRole::getCreateTime)
        );
        return list.stream().map(SysRole::getDisplayName).collect(Collectors.toList());
    }

    @Override
    public List<SysRoleResource> getRoleResourceRelations() {
        return roleResourceService.list();
    }
}
